﻿using System.Collections.ObjectModel;
using System.Drawing.Printing;
using System.Reflection;
using System.Windows;
using D.WPF.MVVM;
using D.WPF.MVVM.EventUtil;
using DelegateCommand = D.WPF.MVVM.EventUtil.DelegateCommand;

namespace CarAppClient.ViewModels
{
    public abstract class BaseCrudViewModel<T> : BaseMvvm where T : class
    {
        #region 分页查询参数
        private int pageSize = 20;
        /// <summary>
        /// 每页的记录数
        /// </summary>
        public int PageSize
        {
            get { return pageSize; }
            set { pageSize = value; RaisePropertyChanged(); }
        }

        private int pageNo = 1;
        /// <summary>
        /// 当前页索引
        /// </summary>
        public int PageNo
        {
            get { return pageNo; }
            set { pageNo = value; RaisePropertyChanged(); }
        }

        private int totalCount = 0;
        /// <summary>
        /// 总条数
        /// </summary>
        public int TotalCount
        {
            get { return totalCount; }
            set { totalCount = value; RaisePropertyChanged(); }
        }

        private int totalPage = 1;
        /// <summary>
        /// 总页数
        /// </summary>
        public int TotalPage
        {
            get { return totalPage; }
            set { totalPage = value; RaisePropertyChanged(); }
        }
        #endregion

        #region 单个勾选修改参数

        private T selectedModel;
        /// <summary>
        /// 名称
        /// </summary>
        public T SelectedModel
        {
            get { return selectedModel; }
            set { selectedModel = value; RaisePropertyChanged(); SelectedModelChange(SelectedModel); }
        }
        #endregion

        #region 表格数据源绑定

        private ObservableCollection<T> data;
        /// <summary>
        /// 查询的列表数据
        /// </summary>
        public ObservableCollection<T> Data
        {
            get { return data; }
            set { data = value; RaisePropertyChanged(); }
        }
        #endregion

        #region 操作按钮显示隐藏权限

        private Visibility addBtnVisibility = Visibility.Visible;
        /// <summary>
        /// 新增按钮状态
        /// </summary>
        public Visibility AddBtnVisibility
        {
            get { return addBtnVisibility; }
            set { addBtnVisibility = value; RaisePropertyChanged(); }
        }

        private Visibility deleteBtnVisibility = Visibility.Visible;
        /// <summary>
        /// 删除按钮状态
        /// </summary>
        public Visibility DeleteBtnVisibility
        {
            get { return deleteBtnVisibility; }
            set { deleteBtnVisibility = value; RaisePropertyChanged(); }
        }

        private Visibility updateBtnVisibility = Visibility.Visible;
        /// <summary>
        /// 修改按钮状态
        /// </summary>
        public Visibility UpdateBtnVisibility
        {
            get { return updateBtnVisibility; }
            set { updateBtnVisibility = value; RaisePropertyChanged(); }
        }

        private Visibility exportBtnVisibility = Visibility.Visible;
        /// <summary>
        /// 导出按钮状态
        /// </summary>
        public Visibility ExportBtnVisibility
        {
            get { return exportBtnVisibility; }
            set { exportBtnVisibility = value; RaisePropertyChanged(); }
        }


        #endregion

        #region 操作按钮状态
        private bool exportBtnEnabled = true;
        /// <summary>
        /// 导出按钮状态
        /// </summary>
        public bool ExportBtnEnabled
        {
            get { return exportBtnEnabled; }
            set { exportBtnEnabled = value; RaisePropertyChanged(); }
        }

        private bool updateBtnEnabled = true;
        /// <summary>
        /// 修改按钮状态
        /// </summary>
        public bool UpdateBtnEnabled
        {
            get { return updateBtnEnabled; }
            set { updateBtnEnabled = value; RaisePropertyChanged(); }
        }

        private bool deleteBtnEnabled = true;
        /// <summary>
        /// 删除按钮状态
        /// </summary>
        public bool DeleteBtnEnabled
        {
            get { return deleteBtnEnabled; }
            set { deleteBtnEnabled = value; RaisePropertyChanged(); }
        }

        #endregion

        #region 新增
        /// <summary>
        /// 新增事件
        /// </summary>
        private DelegateCommand? _addCommand;
        /// <summary>
        /// 新增事件
        /// </summary>
        public DelegateCommand AddCommand => _addCommand ?? (_addCommand = new DelegateCommand(Add));
        /// <summary>
        /// 新增
        /// </summary>
        protected virtual void Add(object? obj) { }
        #endregion

        #region 删除
        /// <summary>
        /// 删除事件
        /// </summary>
        private DelegateCommandT<T>? _deleteCommand;
        /// <summary>
        /// 删除事件
        /// </summary>
        public DelegateCommandT<T> DeleteCommand => _deleteCommand ?? (_deleteCommand = new DelegateCommandT<T>(Delete));
        /// <summary>
        /// 单个删除
        /// </summary>
        /// <param name="obj"></param>
        protected virtual void Delete(T obj) { }
        #endregion

        #region 批量删除
        /// <summary>
        /// 批量删除事件
        /// </summary>
        private DelegateCommand? _batchDeleteCommand;
        /// <summary>
        /// 批量删除事件
        /// </summary>
        public DelegateCommand BatchDeleteCommand => _batchDeleteCommand ?? (_batchDeleteCommand = new DelegateCommand(BatchDelete));
        protected virtual void BatchDelete(object? obj) { }

        #endregion

        #region 修改  
        /// <summary>
        /// 修改事件
        /// </summary>
        private DelegateCommandT<T>? _updateCommand;
        /// <summary>
        /// 修改事件
        /// </summary>
        public DelegateCommandT<T> UpdateCommand => _updateCommand ?? (_updateCommand = new DelegateCommandT<T>(Update));
        /// <summary>
        /// 修改
        /// </summary>
        protected virtual void Update(T? vm)
        {

        }
        #endregion

        #region 查询
        /// <summary>
        /// 查询事件
        /// </summary>
        private DelegateCommand? _queryCommand;
        /// <summary>
        /// 查询事件
        /// </summary>
        public DelegateCommand QueryCommand => _queryCommand ?? (_queryCommand = new DelegateCommand(Query));
        /// <summary>
        /// 查询
        /// </summary>
        /// <param name="obj"></param>
        protected virtual void Query(object? obj = null) { }
        #endregion

        #region 导出
        /// <summary>
        /// 导出事件
        /// </summary>
        private DelegateCommand? _exportCommand;
        /// <summary>
        /// 导出事件
        /// </summary>
        public DelegateCommand ExportCommand => _exportCommand ?? (_exportCommand = new DelegateCommand(Export));
        /// <summary>
        /// 导出
        /// </summary>
        /// <param name="obj"></param>
        protected virtual void Export(object? obj) { }
        #endregion

        #region 导入
        /// <summary>
        /// 导入事件
        /// </summary>
        private DelegateCommand? _importCommand;
        /// <summary>
        /// 导入事件
        /// </summary>
        public DelegateCommand ImportCommand => _importCommand ?? (_importCommand = new DelegateCommand(Import));
        /// <summary>
        /// 导入
        /// </summary>
        /// <param name="obj"></param>
        protected virtual void Import(object? obj) { }
        #endregion

        #region 重置

        /// <summary>
        /// 重置事件
        /// </summary>
        private DelegateCommand? resetCommand;
        /// <summary>
        /// 重置事件
        /// </summary>
        public DelegateCommand ResetCommand => resetCommand ?? (resetCommand = new DelegateCommand(Reset));
        /// <summary>
        /// 重置
        /// </summary>
        /// <param name="obj"></param>
        protected virtual void Reset(object? obj)
        {
            PageSize = 20;
            PageNo = 1;
            TotalCount = 0;
            TotalPage = 0;
        }
        #endregion

        #region 切换每页显示条数

        /// <summary>
        /// 切换每页显示条数事件
        /// </summary>
        private DelegateCommand? _pageSizeChangeCommand;
        /// <summary>
        /// 切换每页显示条数事件
        /// </summary>
        public DelegateCommand PageSizeChangeCommand => _pageSizeChangeCommand ?? (_pageSizeChangeCommand = new DelegateCommand(PageSizeChange));
        /// <summary>
        /// 切换每页显示条数
        /// </summary>
        /// <param name="obj"></param>
        protected virtual void PageSizeChange(object? obj)
        {
            if (obj != null)
            {
                // 每次切换时，页码重置为1
                PageNo = 1;

                var Content = ((System.Windows.Controls.ContentControl)obj).Content;
                switch (Content)
                {
                    case "20条/页": PageSize = 20; Query(); break;
                    case "50条/页": PageSize = 50; Query(); break;
                    case "100条/页": PageSize = 100; Query(); break;
                    case "200条/页": PageSize = 200; Query(); break;
                }
            }
        }
        #endregion

        #region 分页-第一页
        private bool canFrist = false;
        /// <summary>
        /// 第一页按钮状态
        /// </summary>
        public bool CanFrist
        {
            get { return canFrist; }
            set { canFrist = value; RaisePropertyChanged(); }
        }
        /// <summary>
        /// 第一页事件
        /// </summary>
        private DelegateCommand? _firstPageCommand;
        /// <summary>
        /// 第一页事件
        /// </summary>
        public DelegateCommand FirstPageCommand => _firstPageCommand ?? (_firstPageCommand = new DelegateCommand(FirstPage));
        /// <summary>
        /// 第一页
        /// </summary>
        /// <param name="obj"></param>
        protected virtual void FirstPage(object? obj)
        {
            PageNo = 1; // 第一页
            Query();
        }
        #endregion

        #region 分页-上一页
        private bool canPrevious = false;
        /// <summary>
        /// 上一页按钮状态
        /// </summary>
        public bool CanPrevious
        {
            get { return canPrevious; }
            set { canPrevious = value; RaisePropertyChanged(); }
        }

        /// <summary>
        /// 上一页事件
        /// </summary>
        private DelegateCommand? _previousPageCommand;
        /// <summary>
        /// 上一页事件
        /// </summary>
        public DelegateCommand PreviousPageCommand => _previousPageCommand ?? (_previousPageCommand = new DelegateCommand(PreviousPage));
        /// <summary>
        /// 上一页
        /// </summary>
        /// <param name="obj"></param>
        protected virtual void PreviousPage(object? obj)
        {
            PageNo--; //减少一页
            Query();
        }
        #endregion

        #region 分页-下一页
        private bool canNext = false;
        /// <summary>
        /// 下一页按钮状态
        /// </summary>
        public bool CanNext
        {
            get { return canNext; }
            set { canNext = value; RaisePropertyChanged(); }
        }

        /// <summary>
        /// 下一页事件
        /// </summary>
        private DelegateCommand? _nextPageCommand;
        /// <summary>
        /// 下一页事件
        /// </summary>
        public DelegateCommand NextPageCommand => _nextPageCommand ?? (_nextPageCommand = new DelegateCommand(NextPage));
        /// <summary>
        /// 下一页
        /// </summary>
        /// <param name="obj"></param>
        protected virtual void NextPage(object? obj)
        {
            PageNo++; //增加一页 
            Query();
        }
        #endregion

        #region 分页-最后一页

        private bool canLast = false;
        /// <summary>
        /// 最后一页按钮状态
        /// </summary>
        public bool CanLast
        {
            get { return canLast; }
            set { canLast = value; RaisePropertyChanged(); }
        }
        /// <summary>
        /// 最后一页事件
        /// </summary>
        private DelegateCommand? _lastPageCommand;
        /// <summary>
        /// 最后一页事件
        /// </summary>
        public DelegateCommand LastPageCommand => _lastPageCommand ?? (_lastPageCommand = new DelegateCommand(LastPage));
        /// <summary>
        /// 最后一页
        /// </summary>
        /// <param name="obj"></param>
        protected virtual void LastPage(object? obj)
        {
            PageNo = TotalPage;//最后一页 将总页码赋值给当前页
            Query();
        }
        #endregion

        #region 更新分页插件按钮状态
        protected virtual void RefPage()
        {
            if (TotalPage == 1 && PageNo == 1)
            {// 全部禁用，不到一页
                CanFrist = false;
                CanPrevious = false;
                CanLast = false;
                CanNext = false;
            }else if(TotalPage > 1 && PageNo == 1)
            {// 首页，上一页禁用，显示下一页，显示最后一页
                CanFrist = false;
                CanPrevious = false;
                CanLast = true;
                CanNext = true;
            }
            else if (TotalPage > 1 && PageNo < TotalPage)
            {// 显示下一页，显示最后一页，大于一页 不是最后一页
                CanFrist = true;
                CanPrevious = true;
                CanLast = true;
                CanNext = true;
            }
            else if (PageNo == TotalPage && TotalPage != 1)
            {// 显示首页，上一页,禁用下一页，禁用最后一页
                CanFrist = true;
                CanPrevious = true;
                CanLast = false;
                CanNext = false;
            }
        }
        #endregion

        protected virtual void SelectedModelChange(object? obj = null) { }

        #region 全选
        public bool CheckAll
        {
            get => _checkAll;
            set
            {
                SetProperty(ref _checkAll, value);
                ObservableCollection<T> dataTemp = Data;
                foreach (var item in dataTemp)
                {
                    //item.IsSelected = value;
                    // 获取类型信息
                    Type type = item.GetType();
                    // 获取 MyBoolProperty 属性信息
                    PropertyInfo propertyInfo = type.GetProperty("IsSelected");

                    if (propertyInfo != null && propertyInfo.CanWrite)
                    {
                        // 使用反射设置属性值
                        propertyInfo.SetValue(item, value, null);
                    }
                }
                Data = dataTemp;
            }
        }

        private bool _checkAll; //全选
        #endregion
    }
}
